import axios from 'axios';
import type { AxiosInstance, AxiosRequestConfig } from 'axios';
import { getToken, setToken } from '@/utils/auth';
import { API, TIMEOUT } from '@/config';
import { toast } from '@/utils';
import router from '@/router';
import { useBackStore } from '@/store/background';

const service: AxiosInstance = axios.create({
  baseURL: API(),
  timeout: TIMEOUT,
});

service.interceptors.request.use(req => {
  if (!req.headers.Authorization) req.headers.Authorization = getToken() || '';
  return req;
});

service.interceptors.response.use(
  res => {
    const contentType = res.headers['content-type'];
    const token = res.headers['Token'] || res.headers['token'];
    token && setToken(token);
    if (contentType && contentType.startsWith('image')) {
      const captcha = res.headers['Captcha'] || res.headers['captcha'] || '';
      useBackStore().setCaptcha(captcha);
      // 处理图片响应
      return res.data;
    }
    const { code, data, msg, rows, total } = res.data;
    if (code === 0 && msg !== '') {
      toast(msg);
      return data;
    } else if (code === 1) {
      return {
        rows,
        total,
      };
    } else if (code == 2) {
      toast(msg, 'error');
      return Promise.reject(msg);
    } else if (code === 3) {
      toast(msg, 'error');
      router.push('/login');
      return Promise.reject(msg);
    }
    return data;
  },
  err => {
    if (
      err.code === 'ECONNABORTED' ||
      err.message === 'Network Error' ||
      err.message.includes('timeout')
    ) {
      toast('网络超时', 'error');
      Promise.reject(err);
    }
  },
);

function request(options: AxiosRequestConfig) {
  const methodName = options.method || 'get';
  if (methodName.toLowerCase() === 'get') {
    options.params = options.data;
  }
  return service(options);
}

request.get = (url: string, data?: any, options?: AxiosRequestConfig) =>
  request({ url, data, method: 'get', ...options });
request.post = (url: string, data: any, options?: AxiosRequestConfig) =>
  request({ url, data, method: 'post', ...options });
request.put = (url: string, data: any, options?: AxiosRequestConfig) =>
  request({ url, data, method: 'put', ...options });
request.delete = (url: string, data: any, options?: AxiosRequestConfig) =>
  request({ url, data, method: 'delete', ...options });
request.patch = (url: string, data: any, options?: AxiosRequestConfig) =>
  request({ url, data, method: 'patch', ...options });

export default request;
